--[[
-- Author:      feilong
-- DateTime:    2020-10-10 17:19:33
-- Description: 
    经常变动的个人属性
    1先从Redis取数据，没有再从mongo取,写到Redis
    2数据发生改变写到Redis队列中，由每三方节点落地
--]]


local skynet = require "skynet"
local lfs = require "lfs"

local server_config = dofile(skynet.getenv("server_config"))


local table_insert = table.insert
local table_remove = table.remove
local table_unpack = table.unpack
local math_floor = math.floor
local math_random = math.random
local math_abs = math.abs




local MessageHandler = class("MessageHandler")

---------------------------------------------------------
-- Private
---------------------------------------------------------
function MessageHandler:ctor()

    self.game_session_counter = 0 --客户端唯一标识
    self.client_sessions = {} --
    self.game_session_fds = {}
    self.client_pack = new("client_pack")

    --socket状态消息
    self.socket_handler = {}

	self:register()	
end

--注册本服务里的消息
function MessageHandler:register()    
    self.message_dispatch = g.MsgDis()
    self.message_dispatch:register("start", handler(self, self.start))
    self.message_dispatch:register("get_base_data", handler(self, self.getBaseData))
end

--redis结果如hmap转为table(第一个参数是key, 第二个参数是value)
function MessageHandler:resToTable(res)
    if not res or type(res) ~= "table" then 
        return res
    end
    local data = {}
    for i=1, #res, 2 do
        data[res[i]] = res[i+1]
    end
    return data
end

function MessageHandler:select_from_mongodb(uid)
    local collection_name = "base"
    return g.Message():callService(".mongo", collection_name, "findOne", {_id = tonumber(uid)})
end
--先把数据写入,再做一个写标记，切记不可调换。用脚本同时可保证数据写入的原子性 key缓存一天失效
local update_redis_script = [[
    redis.call('set',KEYS[1],ARGV[1])
    redis.call('expire',KEYS[1], 86400)
    redis.call('select',KEYS[2])
    redis.call('hincrby',KEYS[3],ARGV[2],ARGV[3])
]]

function MessageHandler:create_default_base_data(uid)
    local new_data = {uid = uid}
    self:fix_base_data_for_miss_field(new_data)
    return new_data
end

function MessageHandler:save_data_to_cache(uid, data)
    local key = string_format('base_%d', uid)
    local data_str = cjson.encode(data)
    g.Message():callService(".redis", uid, "eval", update_redis_script, 3, key, dirty_queue_db,
        dirty_queue_key, data_str, uid, 1)
end

--从redis取
function MessageHandler:ensure_data_in_cache(uid)
    local key = string_format('base_%d',uid)
    local data = g.Message():callService(".redis", uid, "get", key)
    --dbglog(uid,"-----ensure_data_in_cache-----",data)
    if data then
        data = cjson.decode(data)
        if self:fix_base_data_for_miss_field(data) then
            self:save_data_to_cache(uid, data)
        end
    else
        --缓存没命中，在数据库里？我们需要到mongodb上找去
        data = self:select_from_mongodb(uid)
        if not data then
            --数据库也没有，这是一个新玩家，我们用默认的数据吧
            data = self:create_default_base_data(uid)
            self:save_data_to_cache(uid, data)
        else
            self:fix_base_data_for_miss_field(data)
            --写到缓存中去吧
            self:save_data_to_cache(uid, data)
        end  
    end

    return data
end

function MessageHandler:fix_base_data_for_miss_field(data)
    local changed = false
    if not data.coins then
        data.coins = init_coins
        changed = true
    end
    if not data.gems then
        data.gems = init_gems
        changed = true
    end
    if not data.max_gems then
        data.max_gems = data.gems
        changed = true
    end
    if not data.roomcards then
        data.roomcards = init_roomcards
        changed = true
    end
    if not data.rate_of_winning then
        data.rate_of_winning = {}
        changed = true
    end

    if not data.created_time then
        data.created_time = util.get_now_time()
        changed = true
    end
    if not data.compensation_times then
        data.compensation_times = 0
        changed = true
    end
    if not data.last_cross_day_time then
        data.last_cross_day_time = 0
        changed = true
    end
    if not data.last_cross_timing_time then
        data.last_cross_timing_time = 0
        changed = true
    end
    if not data.jiabei_cards then
        data.jiabei_cards = 0
        changed = true
    end
    if not data.card_note_count then
        data.card_note_count = 1
        changed = true
    end
    if not data.card_note_end_time then
        data.card_note_end_time = 0
        changed = true
    end
    if not data.coins_locked then
        data.coins_locked = 0
        changed = true
    end
    if not data.club_play_times then
        data.club_play_times = 0
        changed = true
    end
    --增加保险箱功能
    if not data.safe_box then
        data.safe_box = 0
        changed = true
    end
    if not data.lose_coins then
        data.lose_coins = 0
        changed = true
    end
    if not data.last_lase_coins_time then
        data.last_lase_coins_time = 0
        changed = true
    end
    --增加个人概率设置
    if not data.affect_count then
        data.affect_count = 0
        changed = true
    end
    if not data.affect_rate then
        data.affect_rate = 0
        changed = true
    end
    if not data.affect_state then
        data.affect_state = 0
        changed = true
    end
    if not data.affect_id then
        data.affect_id = 0
        changed = true
    end

    if not data.charge_count then
        data.charge_count = 0
        changed = true
    end

    if not data.week_award then
        data.week_award = {}
        data.week_award.day_count = 1
        data.week_award.last_check_time = 0
        data.week_award.last_award = 0
        data.week_award.total_award = 0
        data.week_award.today_coins_water = 0
        data.week_award.can_exchange_award = 0
        changed = true
    end

    if not data.pay_money then
        data.pay_money = 0
        changed = true
    end

    if not data.play_time then
        data.play_time = 0
        changed = true
    end

    local now = util.get_now_time()
    if not data.today_win_coins then
        data.today_win_coins = 0
        changed = true
    end
    if not data.last_tw_coins_time then
        data.last_tw_coins_time = now
        changed = true
    end
    if not data.today_exchange_coins then --今日兑换
        data.today_exchange_coins = 0
        changed = true
    end
    if not data.exchange_coins then --累计兑换
        data.exchange_coins = 0
        changed = true
    end   
    if not data.last_te_coins_time then
        data.last_te_coins_time = now
        changed = true
    end
    if not data.today_online_seconds then
        data.today_online_seconds = 0
        changed = true
    end
    if not data.last_to_seconds_time then
        data.last_to_seconds_time = now
        changed = true
    end
    
    --fishing
    if not data.winlose_coins then     --捕鱼玩家输赢
        data.winlose_coins = 0
        changed = true
    end

    if not data.jackpots then           --捕鱼玩家个人奖池
        data.jackpots = {}
        changed = true
    end

    if not data.contribution then       --玩家贡献
        data.contribution = {}
        changed = true
    end

    if not data.hitrate then            --玩家概率
        data.hitrate = 1
        changed = true
    end

    if not data.person_rate then         --个人概率控制
        data.person_rate = 1
        changed = true
    end

    if not data.person_water then            --个人流水
        data.person_water = 0
        changed = true
    end

    if not data.person_water2 then            --达到首充要求后的个人流水
        data.person_water2 = 0
        changed = true
    end

    if not data.person_water_today then     --当日流水
        data.person_water_today = 0
        changed = true
    end

    if not data.person_water_month then    --当月流水
        data.person_water_month = 0
        changed = true
    end

    if not data.person_water_today_copy then --一日流水副本
        data.person_water_today_copy = 0
        changed = true
    end

    if not data.person_water_copy_time then -- 流水副本时间
        data.person_water_copy_time = 0
        changed = true
    end

    if not data.vip_level then
        data.vip_level = 0
        changed = true
    end

    if not data.total_free_times then     --老虎机总共获得的免费次数
        data.total_free_times = 0
        changed = true
    end

    if not data.free_times_data then      --获的免费次数时的下注额度和押线
        data.free_times_data = {}
        changed = true
    end

    if not data.last_caishen_trigger_time then
        data.last_caishen_trigger_time = 0
        changed = true
    end

    if not data.bind_uid then
        data.bind_uid = 0
        changed = true
    end
    if not data.play_count then --玩牌局数
        data.play_count = 0
        changed = true
    end

    if not data.fish_guns then
        data.fish_guns = {}
        changed = true
    end

    if not data.first_charge_status then
        data.first_charge_status = 0
        changed = true
    end

    if not data.ex_money then
        data.ex_money = 0
        changed = true
    end

    if not data.total_win_coins then
        data.total_win_coins = 0
        changed = true
    end

    if not data.total_lose_coins then
        data.total_lose_coins = 0
        changed = true
    end

    if not data.total_fee_coins then
        data.total_fee_coins = 0
        changed = true
    end

     if not data.club_info then
        data.club_info = {}
        data.club_info.club_id = 0
        data.club_info.last_play_time = 0
        changed = true
    end

    if not data.award_info then
        data.award_info = {}
        data.award_info.award_free_times = 0
        data.award_info.free_valid_time = 0
        changed = true
    end

    --兑换所需
    if not data.exchange_need_water then
        data.exchange_need_water = 0
        changed = true
    end

    --我的抢红包战绩
    if not data.qhb_record then
        data.qhb_record = {}
        changed = true
    end

    --我的发红包战绩
    if not data.fhb_record then
        data.fhb_record = {}
        changed = true
    end

    --今日总充值
    if not data.today_pay_money then
        data.today_pay_money = 0
        changed = true
    end

    --今日金钱时间戳
    if not data.pay_money_time then
        data.pay_money_time = 0
        changed = true
    end

    --首次充值时间
    if not data.first_recharge_time then
        data.first_recharge_time = 0
        changed = true
    end
    --最后充值时间
    if not data.last_recharge_time then
        data.last_recharge_time = 0
        changed = true
    end

    --游戏胜负（扣台费）
    if not data.win_lose_today then
        data.win_lose_today = 0
        changed = true
    end

    --游戏胜负副本（扣台费）
    if not data.win_lose_today_copy then
        data.win_lose_today_copy = 0
        changed = true
    end

    --每日首充
    if not data.day_charge_status then
        data.day_charge_status = 0
        changed = true
    end    

    --gm控制
    if not data.gm_control then
        data.gm_control = {}
        data.gm_control.weight    = 0 --权重值
        data.gm_control.win_rate  = 0
        data.gm_control.lose_rate = 0
        data.gm_control.control_coins = 0
        data.gm_control.control_coins_init = 0
        data.gm_control.is_control_hundred_game = 0 
        data.gm_control.oper_user = ""
        changed = true
    end

    --个控 
    if not data.personal_control then
        data.personal_control = {}
        data.personal_control.control_coins_init = 0
        data.personal_control.control_coins = 0
        data.personal_control.weight = 0
        data.personal_control.win_rate  = 0
        data.personal_control.lose_rate = 0
        changed = true
    end

    return changed
end










---------------------------------------------------------
-- CMD
---------------------------------------------------------
function MessageHandler:start()

  
end

function MessageHandler:getBaseData(uid)
   print("____getBaseData______", uid)
   local data = self:ensure_data_in_cache(uid)
   print("________data__", data)
end







return MessageHandler